{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "所有LLM都实现了Runnable接口，它带有标准可运行方法的默认实现（ainvoke、batch、abatch、stream、astream、astream_events）。\n",
    "- 对 Runnable 接口中主要方法的简要说明：\n",
    "\n",
    "1. ainvoke: 异步调用方法，用于单个输入的异步处理。这通常用于需要非阻塞执行的情况，例如在事件驱动或高并发的应用场景中。\n",
    "\n",
    "2. batch: 同步批量调用方法，用于同时处理多个输入。这对于提高效率和减少延迟特别有用，尤其是在处理大量数据时。\n",
    "\n",
    "3. abatch: 异步批量调用方法，结合了批量处理和异步执行的优点，适用于大规模并行处理。\n",
    "\n",
    "4. stream: 同步流式调用方法，允许逐步接收输出，而不是一次性返回所有结果。这对于处理大型或连续的数据流非常有用。\n",
    "\n",
    "5. astream: 异步流式调用方法，提供了流式处理的异步版本，适合于需要实时响应的场景。\n",
    "\n",
    "6. astream_events: 异步事件流调用方法，用于生成一系列事件，每个事件可能代表部分输出或状态更新。\n",
    "\n",
    "这些方法的实现通常依赖于底层语言模型的 API 和功能。通过将这些方法标准化，Runnable 接口使得在不同的 LLM 实现之间切换变得更容易，同时也为开发者提供了统一的编程接口，简化了应用开发流程。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_openai import OpenAI\n",
    "\n",
    "llm = OpenAI(model=\"gpt-3.5-turbo-instruct\", temperature=0, max_tokens=512)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1. 流式输出"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "|Lang|chain|框|架|是|一|种|用|于|构|建|多|语|言|应|用|程序|的|开|发|框|架|。|它|提|供|了|一|套|简|单|易|用|的|工|具|和|方法|，|帮|助|开|发|者|轻|松|地|实|现|多|语|言|支|持|，|从|而|使|应|用|程序|能|够|适|应|不|同|语|言|环|境|下|的|用户|。\n",
      "\n",
      "|该|框|架|的|核|心|思|想|是|将|应|用|程序|的|文|本|内容|和|语|言|相关|的|信息|分|离|，|从|而|实|现|语|言|的|可|配置|性|。|开|发|者|只|需要|在|应|用|程序|中|使用|特|定|的|标|记|来|标|识|需要|翻|译|的|文|本|，|然|后|将|这|些|文|本|放|入|语|言|文件|中|，|就|可以|实|现|多|语|言|支|持|。|这|样|一|来|，|开|发|者|就|可以|专|注|于|应|用|程序|的|逻|辑|和|功能|，|而|不|需要|关|心|语|言|的|翻|译|和|管理|。\n",
      "\n",
      "|Lang|chain|框|架|还|提|供|了|一|些|额|外|的|功能|，|如|语|言|切|换|、|语|言|检|测|和|语|言|文件|管理|等|，|使|开|发|者|能|够|更|加|灵|活|地|控|制|应|用|程序|的|语|言|环|境|。\n",
      "\n",
      "|总|的|来|说|，|Lang|chain|框|架|是|一|种|简|单|、|高|效|的|多|语|言|开|发|框|架|，|能|够|帮|助|开|发|者|快|速|构|建|适|应|不|同|语|言|环|境|的|应|用|程序|，|提|升|用户|体|验|和|应|用|程序|的|可|用|性|。||"
     ]
    }
   ],
   "source": [
    "for chunk in llm.stream(\"用通俗易懂的语言介绍langchain框架\"):\n",
    "    print(chunk, end=\"|\", flush=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2. 异步流式输出"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "|Lang|chain|框|架|是|一|种|用|于|构|建|多|语|言|应|用|程序|的|开|发|框|架|。|它|提|供|了|一|套|简|单|易|用|的|工|具|和|方法|，|帮|助|开|发|者|轻|松|地|实|现|多|语|言|支|持|，|从|而|使|应|用|程序|能|够|适|应|不|同|语|言|环|境|下|的|用户|。\n",
      "\n",
      "|该|框|架|的|核|心|思|想|是|将|应|用|程序|的|文|本|内容|和|语|言|相关|的|信息|分|离|，|从|而|实|现|语|言|的|可|配置|性|。|开|发|者|只|需要|在|应|用|程序|中|使用|特|定|的|标|记|来|标|识|需要|翻|译|的|文|本|，|然|后|将|这|些|文|本|放|入|语|言|文件|中|，|就|可以|实|现|多|语|言|支|持|。|这|样|一|来|，|开|发|者|就|可以|专|注|于|应|用|程序|的|逻|辑|和|功能|，|而|不|需要|关|心|语|言|的|翻|译|和|管理|。\n",
      "\n",
      "|Lang|chain|框|架|还|提|供|了|一|些|额|外|的|功能|，|如|语|言|切|换|、|语|言|检|测|和|语|言|文件|管理|等|，|使|开|发|者|能|够|更|加|灵|活|地|控|制|应|用|程序|的|语|言|环|境|。\n",
      "\n",
      "|总|的|来|说|，|Lang|chain|框|架|是|一|种|简|单|、|高|效|的|多|语|言|开|发|框|架|，|能|够|帮|助|开|发|者|快|速|构|建|适|应|不|同|语|言|环|境|的|应|用|程序|，|提|升|用户|体|验|和|应|用|程序|的|可|用|性|。||"
     ]
    }
   ],
   "source": [
    "async for chunk in llm.astream(\"用通俗易懂的语言介绍langchain框架\"):\n",
    "    print(chunk, end=\"|\", flush=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "3. 异步事件流式输出"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'event': 'on_llm_start', 'run_id': '9b73c95b-9385-4147-8a0b-d8c889745298', 'name': 'OpenAI', 'tags': [], 'metadata': {}, 'data': {'input': '写一首关于程序员的诗'}, 'parent_ids': []}\n",
      "{'event': 'on_llm_stream', 'run_id': '9b73c95b-9385-4147-8a0b-d8c889745298', 'tags': [], 'metadata': {}, 'name': 'OpenAI', 'data': {'chunk': '\\n\\n'}, 'parent_ids': []}\n",
      "{'event': 'on_llm_stream', 'run_id': '9b73c95b-9385-4147-8a0b-d8c889745298', 'tags': [], 'metadata': {}, 'name': 'OpenAI', 'data': {'chunk': '程序'}, 'parent_ids': []}\n",
      "{'event': 'on_llm_stream', 'run_id': '9b73c95b-9385-4147-8a0b-d8c889745298', 'tags': [], 'metadata': {}, 'name': 'OpenAI', 'data': {'chunk': '员'}, 'parent_ids': []}\n",
      "...断开输出\n"
     ]
    }
   ],
   "source": [
    "idx = 0\n",
    "\n",
    "async for event in llm.astream_events(\"写一首关于程序员的诗\", version=\"v1\"):\n",
    "    idx += 1\n",
    "    if idx >= 5:\n",
    "        print(\"...断开输出\")\n",
    "        break\n",
    "    print(event)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
